home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / movemail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  3.8 KB  |  193 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. /*
  9.  * program to move file a to file b, obeying file locking.
  10.  * meant to be suid'ed or sgid'ed.   
  11.  *
  12.  * The point is to be able to move a user's mail file out of /usr/spool/mail, 
  13.  * to a file of their own.
  14.  * 
  15.  * Must check accesses of REAL uid, to be sure that the file can be moved.
  16.  * The user must have read access to the original, and write access to the 
  17.  * destination directory.  The destination file must not exist.
  18.  */
  19.  
  20. #ifndef lint
  21. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/movemail.c,v 2.1 90/10/04 18:25:11 melissa Exp $ ";
  22. #endif
  23.  
  24. #include "config.h"
  25. #include "osfiles.h"
  26. #include "compat.h"
  27.  
  28. extern int errno;
  29.  
  30. #define TRUE 1
  31. #define FALSE 0
  32.  
  33. FILE *infile = NULL;
  34. FILE *outfile = NULL;
  35.  
  36. main(argc, argv)
  37. int argc;
  38. char **argv;
  39. {
  40.     if (argc != 3) {
  41.     usage(argv[0]);
  42.     exit(1);
  43.     }
  44.     if (readaccess(argv[1]) &&        /* must be able to read the src */
  45.     writeaccess_dir(argv[2]) &&    /* have write access to the directory*/
  46.                     /* of the destination file */
  47.     !exist(argv[2]) &&        /* the destination cannot exist */
  48.     (locked(argv[1])))        /* and the source cannot be locked */
  49.     {
  50.     return(!movefile(argv[1], argv[2]));    /* do it!! */
  51.     }
  52.     else
  53.     return(1);
  54. }
  55.  
  56. usage(pname) 
  57. char *pname;
  58. {
  59.     fprintf(stderr,"Usage: %s srcfile destfile\n", pname);
  60. }
  61.  
  62. /*
  63.  * check if the real user (no suid/sgid bits considered) is readable
  64.  */
  65. readaccess(fname)
  66. char *fname;
  67. {
  68.     if (access(fname,R_OK)) {
  69.     perror(fname);
  70.     return(FALSE);
  71.     }
  72.     return(TRUE);
  73. }
  74.     
  75. writeaccess_dir(fname)
  76. char *fname;
  77. {
  78.     char *cp, *rindex();
  79.     char c;
  80.  
  81.     cp = rindex(fname,'/');
  82.     if (cp) {
  83.     c = *(++cp);
  84.     *cp = '\0';
  85.     if (access(fname,W_OK) != 0) {
  86.         perror(fname);
  87.         return(FALSE);
  88.     }
  89.     *cp = c;
  90.     return(TRUE);
  91.     }
  92.     else if (access(".", W_OK) != 0){
  93.     perror(fname);
  94.     return(FALSE);
  95.     }
  96.     return(TRUE);
  97. }
  98.  
  99. exist(fname)
  100. {
  101.     if (access(fname,F_OK) == 0) {
  102.     fprintf(stderr,"%s: file exists\n", fname);
  103.     return(TRUE);
  104.     }
  105.     return(FALSE);
  106. }
  107.  
  108.  
  109. locked(fname)
  110. char *fname;
  111. {
  112.     char buf[MAXPATHLEN];
  113.  
  114.     infile = fopen(fname,"r");        /* open the input file */
  115.     if (infile == NULL) {
  116.     perror(fname);
  117.     return(FALSE);
  118.     }
  119.     return(lock(infile, fname));    /* and lock it */
  120. }
  121.  
  122. /* 
  123.  * move from "from" to "to"
  124.  */
  125. movefile(from, to)
  126. char *from;
  127. char *to;
  128. {
  129.     int c;
  130.     outfile = fopen(to, "w");
  131.     if (outfile == NULL) {        /* can't open....stop */
  132.     perror(to);
  133.     unlock(infile,from);        /* but unlock the locked file */
  134.     return(FALSE);
  135.     }
  136.     while((c = getc(infile)) != EOF)    /* copy */
  137.     if (putc(c,outfile) == EOF) {
  138.         fclose(outfile);
  139.         unlink(outfile);
  140.         unlock(infile,from);
  141.         return(FALSE);
  142.     }
  143.     if (fclose(outfile) == EOF) {    /* error flushing */
  144.     unlink(outfile);
  145.     unlock(infile,from);
  146.     return(FALSE);
  147.     }
  148.     if (unlink(from) < 0) {        /* unlink the original, */
  149.     truncate(from,0);        /* or at least truncate it */
  150.     }
  151.     unlock(infile,from);        /* unlock the source. */
  152.     return(TRUE);
  153. }
  154.  
  155.  
  156. lock(fp, fname)
  157. FILE *fp;
  158. char *fname;
  159. {
  160. #ifdef MAIL_USE_FLOCK
  161.     if (flock(fileno(fp),LOCK_EX|LOCK_NB) < 0) {
  162.     fprintf(stderr,"%s: already locked\n",fname);
  163.     return(FALSE);
  164.     }
  165. #else
  166.     char buf[MAXPATHLEN];
  167.     int fd;
  168.     sprintf(buf,"%s.lock", fname);
  169.     if ((fd = open(buf,O_CREAT|O_EXCL|O_WRONLY, 0)) < 0) {
  170.     if (errno == EEXIST)
  171.         fprintf(stderr,"%s: already locked\n",fname);
  172.     else
  173.         perror(buf);
  174.     return(FALSE);
  175.     }
  176. #endif
  177.     return(TRUE);
  178. }
  179.  
  180. unlock(fp,fname)
  181. FILE *fp;
  182. char *fname;
  183. {
  184. #ifdef MAIL_USE_FLOCK
  185.     flock(fileno(fp),LOCK_EX|LOCK_UN);
  186. #else
  187.     char buf[MAXPATHLEN];
  188.     sprintf(buf,"%s.lock", fname);
  189.     unlink(buf);
  190. #endif
  191.     return(TRUE);
  192. }
  193.